package com.easyaop.api.event;

import com.easyaop.api.Context;
import com.easyaop.api.event.listener.MethodListener;
import com.easyaop.api.join.JoinImpl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public final class JoinManger {
    // private static final long fieldOffset;

    private static final MethodListener[] m = new MethodListener[0];

    // private static final Field declaredField;

    // private static final VarHandle

    public static void enter(JoinImpl join) throws Exception {
        Iterable<MethodListener> listenerIterable = Context.getListeners(join.getSignature());
        // MethodListener[] methodListeners= (MethodListener[]) UnsafeUtils.unsafe.getObject(listeners,fieldOffset);

        if (listenerIterable == null) {
            return;
        }
        List<MethodListener> listeners = new ArrayList<>();
        Iterator<MethodListener> iterator = listenerIterable.iterator();
        while (iterator.hasNext()) {
            listeners.add(iterator.next());
        }

        MethodListener[] methodListeners = listeners.toArray(m);
        join.setListeners(methodListeners);

        for (int i = 0, size = listeners.size(); i < size; i++, join.listenerIndex = i) {
            MethodListener methodListener = methodListeners[i];
            methodListener.before(join);
        }
    }

    public static void exit(JoinImpl join) {
        MethodListener[] methodListeners = join.getListeners();
        if (methodListeners == null) {
            return;
        }

        for (int i = 0, size = methodListeners.length; i < size; i++) {
            join.listenerIndex = i;
            MethodListener methodListener = methodListeners[i];
            methodListener.afterReturn(join);
        }
    }

    public static void onThrows(JoinImpl join) {
        MethodListener[] methodListeners = join.getListeners();
        if (methodListeners == null) {
            return;
        }

        for (int i = 0, size = methodListeners.length; i < size; i++) {
            join.listenerIndex = i;
            MethodListener methodListener = methodListeners[i];
            methodListener.exception(join);
        }
    }

}
